<?php
/**
 * Created by PhpStorm.
 * User: 86188
 * Date: 2021/1/13
 * Time: 15:58
 */

namespace app\admin\controller;
use app\service\billService;
use app\service\invoiceService;
use app\service\roominfoService;
use invoice\InvoiceApi;
use think\facade\Db;

class Billinvoice extends Common
{
    public function test(){
        //212.129.153.211 db.zaozao.insert({"name":"菜鸟教程"})
        $mongo = new \MongoClient('mongodb://212.129.153.211:27016');
        $db = $mongo->zaozao;//选择数据库
        $collection = $db->friend;//选择文档集合
        $doc = [//定义一个文档，即一个数组
            'First Name' => 'Jet',
            'Last Name' => 'Wu',
            'Age' => 26,
            'Phone' => '110',
            'Address' => [
                'Country' => 'China',
                'City' => 'Shen Zhen'
            ],
            'E-Mail' => [
                '123456@qq.com',
                '666666@sina.com',
                '8888888@qq.com',
                '77887788@qq.com'
            ]
        ];
        $res = $collection->insert($doc);//向集合中插入一个文档
        echo '<pre>';
        print_r($res);//$res['ok']=1表示插入成功
    }
    public function invoicelist(){
        //查询小区信息
        $com = $this->pidTokenId();
        $whe['community_id'] = array('in',$com['community_id']);
        $communitylist = (new roominfoService())->communityList($whe);
        $community_id = $com['community_id'];
        View::assign('communitylist',$communitylist);

        //搜索时
        $data = request()->get();
        //var_dump($data);
        $where=array();
        $whereb=array();
        $out_room_id=array();
        if (!empty($data)){
            if(!empty($data["community_id"])){
                $where["a.community_id"]=$data["community_id"];
            }
            if(!empty($data["invoice_type"])){
                $where["a.invoice_type"]=$data["invoice_type"];
            }
            if((!empty($data['start_time']))&&(empty($data['end_time']))){
                $where['a.invoice_time']=['>=',$data['start_time']];

            }
            if((!empty($data['end_time']))&&(empty($data['start_time']))){
                $where['a.invoice_time']=['<=',$data['end_time']];

            }
            if((!empty($data['start_time']))&&(!empty($data['end_time']))){

                $where['a.invoice_time']=[ [">=",$data['start_time']],["<=",$data['end_time']],'and'];
            }
            if(!empty($data["owner_name"])){
                $whereb["owner_name"]= ['like','%'.$data["owner_name"].'%'];
            }
            if(!empty($data["owner_phone"])){
                $whereb["owner_phone"]=['like','%'.$data["owner_phone"].'%'];
            }
        }
        if(!empty($whereb)){

            $out_room_id=Db::table("roominfo")->where("community_id","in",$community_id)->where($whereb)->column("out_room_id");
            $where['a.out_room_id']=['in',$out_room_id];

        }
        $page = request()->has('page') ? request()->get('page') : 1;
        $export = $where;
        $export = json_encode($export);
        $export = str_replace("\"","|",$export);
        View::assign('export',$export);

        $exportb=json_encode($whereb);
        $exportb = str_replace("\"","|",$exportb);
        View::assign('exportb',$exportb);
        //var_dump($export);
        //查询账单数据

        $invoicelist = Db::table("billinvoice")
            ->alias("a")
            ->join("community c","a.community_id=c.community_id")
            ->where("a.community_id","in",$community_id)
            ->where($where)
            ->field("a.*,c.community_name")
            ->order("id desc")
            ->paginate(20, false, [
                'page'  =>  $page,
                'query' =>  $where
            ]);

        if(!empty($invoicelist)){
            foreach ($invoicelist as  $key=> &$v){
                $roominfo=Db::table("roominfo")->where("out_room_id",$v["out_room_id"])->find();
                $v["owner_name"]=$roominfo["owner_name"];
                $v["owner_phone"]=$roominfo["owner_phone"];
                $v["address"]=$roominfo["address"];
                $list[] = $v;
                View::assign('list',$list);
            }
        }else{
            View::assign('list',$invoicelist);
        }


        //查询账单条数
        $number = Db::table("billinvoice")
                    ->alias("a")
                    ->where("a.community_id","in",$community_id)
                    ->where($where)
                    ->count();


        View::assign('invoicelist',$invoicelist);
        View::assign('number',$number);

        //var_dump($data);
        foreach ($data as $k => $v) {
            View::assign($k, $v);
        }
        return View::fetch('invoice_list');

    }

    public function billinfo(){
        $id = request()->param('id');

        $billinvoice = Db::table("billinvoice")->where("id",$id)->find();
        $billidarr=unserialize($billinvoice["billid"]);
        $billlist=Db::table("bill")->where("id","in",$billidarr)->select()->toArray();
        View::assign("billlist",$billlist);
        return View::fetch();
    }
    //发票冲红
    public function Cancellation(){
        //判断是否存在该数据
        $id = request()->param('id');
        //var_dump($id);die;
        $billinvoice = Db::table("billinvoice")->where("id",$id)->find();
        if(empty($billinvoice)){
            return '发票信息不存在';
        }
        if($billinvoice["invoice_type"]=="2"){
            return json(['error' => '已冲红']);
        }

        //根据发票号查询开票账单
        $billinfo = (new billService())->numBillInfo($billinvoice['invoice_serial_num']);

        if(empty($billinfo)){
            return json(['error' => '已冲红或未开票']);
        }
        $invoiceDetail=array();
        $out_room_id="";

        //判断房号是否相同
        foreach($billinfo as $inf){


            //根据费用类型查询税率
            $taxrate = (new billService())->taxRateCommunity($inf['cost_type'],$inf['community_id']);
            if(empty($taxrate)){
                $taxrate=0.06;
            }
            $goodsCode=(new billService())->goodsCodeCommunity($inf['cost_type'],$inf['community_id']);
            if(empty($goodsCode)){
                $goodsCode='';
            }

            $tax = $inf['bill_entry_amount']*$taxrate;
            $invoiceDetail[] = "{'goodsName':'{$inf['cost_type']}','specType':'{$inf['acct_period']}','unit':'期','num':'-1','price':'{$inf['bill_entry_amount']}','withTaxFlag':'1','taxRate':'{$taxrate}','tax':'-{$tax}','goodsCode':'{$goodsCode}'}";


            $out_room_id=$inf["out_room_id"];

        }

        $invoiceDetail = implode(',', $invoiceDetail);

        //根据房屋号查询业主信息
        $roominfo = Db::name('roominfo')->where('out_room_id', $out_room_id)->find();
        if(empty($roominfo)){
            return json(['error' => '房屋信息错误']);
        }
        $communityinfo = (new billService())->communityName($roominfo['community_id']);
        $propertyinfo = (new billService())->propertyInfo($communityinfo['property_id']);
        $serviceinfo = (new billService())->serviceInfo($propertyinfo['service_id']);
        //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second < 86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $access_token = $this->accessToken($serviceinfo['fp_app_key'],$serviceinfo['fp_app_secret']);
        }
        $invoiceDate = date('Y-m-d H:i:s',time());
        $orderNo = time().rand(100000,999999);
        $timestmp = time();


        $appKey = $serviceinfo["fp_app_key"];
        $appSecret = $serviceinfo["fp_app_secret"];
        $token = $access_token;// please store the token and refresh it before expired
        $taxnum = $serviceinfo["fp_saler_tax_num"];
        $url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain

        $method2 = "nuonuo.electronInvoice.CheckEInvoice"; // change to your method
        $senid2 = uniqid(); // generate your meaningful senid
        $body2 = json_encode(
            array(
                "invoiceSerialNum" => array($billinvoice['invoice_serial_num'])
            )
        );

        $result2 = InvoiceApi::sendPostSyncRequest($url, $senid2, $appKey, $appSecret, $token, $taxnum, $method2, $body2);
        $result2 = json_decode($result2, true);
        if($result2['code'] != 'E0000'){
            return json(['error' => $result2['describe']]);
        }
        //var_dump($result2);die;
        $invoiceCode = $result2['result'][0]['invoiceCode'];
        $invoiceNum = $result2['result'][0]['invoiceNum'];


        $method = "nuonuo.electronInvoice.requestBilling"; // change to your method
        $senid = uniqid(); // generate your meaningful senid

        $invoiceDate = date('Y-m-d H:i:s',time());
        $orderNo = time().rand(100000,999999);
        $timestmp = time();
        $buyerName=$communityinfo['community_name'].$roominfo['address'].$roominfo['owner_name'];
        $buyerPhone=$roominfo["owner_phone"];
        //$buyerPhone="188561510";
        $fp_saler_tax_num=$serviceinfo['fp_saler_tax_num'];
        $salerAddress=$serviceinfo['address'];
        $salerTel=$serviceinfo['phone'];
        $salerAddress=$serviceinfo['address'];
        $salerAccount=$serviceinfo['fp_saler_account'];
        $body = "{
        \"order\": {
            \"buyerName\": \"$buyerName\",
            \"orderNo\": \"$orderNo\",
            \"invoiceDate\": \"$invoiceDate\",
            \"clerk\": \"\",
            \"salerTaxNum\": \"$fp_saler_tax_num\",
            \"salerTel\": \"$salerTel\",
            \"salerAddress\": \"$salerAddress\",
            \"salerAccount\": \"$salerAccount\",
            \"invoiceType\": \"2\",
            \"invoiceCode\": \"$invoiceCode\",
            \"invoiceNum\": \"$invoiceNum\",
            \"pushMode\": \"1\",
            \"buyerPhone\": \"$buyerPhone\",
            \"invoiceDetail\": [$invoiceDetail],
            \"callBackUrl\": \"\"
            }
        }";



        $result = InvoiceApi::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);
        //var_dump($result);

        $result = json_decode($result, true);
        if($result['code'] == 'E0000'){
            $invoiceSerialNum = $result['result']['invoiceSerialNum'];
            Db::table("billinvoice")
                ->where("id",$id)
                ->update([
                    'invoice_serial_num_red'=>$invoiceSerialNum,
                    'invoice_type'=>2
                ]);
            foreach($billinfo as $inf){
                $data['id'] = $inf['id'];
                $data['invoice_serial_num'] = $invoiceSerialNum;
                $data['invoice_type'] = 2;
                $billinvoiceSerialNum = (new billService())->billApiEdit($data);

            }
            return json(['冲红成功']);
        }else{
            return json(['error' => $result['describe']]);
        }
    }
    public function delivery(){
        if(request()->isPost()){
            $data=request()->post();
            $billinfo = Db::table("billinvoice")->where("id",$data["id"])->find();

            $communityinfo = (new billService())->communityName($billinfo['community_id']);
            $propertyinfo = (new billService())->propertyInfo($communityinfo['property_id']);

            $serviceinfo = (new billService())->serviceInfo($propertyinfo['service_id']);

            //判断access_token是否到期
            $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
            if($second < 86400){
                //未过期
                $access_token = $serviceinfo['fp_access_token'];
            }else{
                //过期从新获取
                $access_token = $this->accessToken($serviceinfo['fp_app_key'],$serviceinfo['fp_app_secret']);
                //return $access_token;
            }
            $phone=$data["phone"];
            $mail=$data["mail"];
            $url = "https://sdk.nuonuo.com/open/v1/services";
            $method = "nuonuo.ElectronInvoice.deliveryInvoice";

            $appKey = $serviceinfo["fp_app_key"];
            $appSecret = $serviceinfo["fp_app_secret"];
            $token = $access_token;// please store the token and refresh it before expired
            $taxnum = $serviceinfo["fp_saler_tax_num"];

            $senid = uniqid(); //唯一标识，由企业自己生成32位随机码
            $body = '{"invoiceSerialNum":["your.voicecode"]}';//API私有请求参数
            $invoiceCode=$billinfo["invoiceCode"];
            $invoiceNum=$billinfo["invoiceNum"];
            $body="{
                  \"mail\": \"$mail\",
                  \"phone\": \"$phone\",
                  \"taxnum\": \"$taxnum\",
                  \"invoiceCode\": \"$invoiceCode\",
                  \"invoiceNum\": \"$invoiceNum\"
                }";
            $res = InvoiceApi::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);
            $result = json_decode($res, true);

            if($result['code'] == 'E0000'){
//
                return "信息推送成功";
            }else{
                return json(['error' => $result['describe']]);
            }
        }else{
            $id=request()->get("id");

            $billinfo = Db::table("billinvoice")->where("id",$id)->find();
            View::assign("info",$billinfo);
            return View::fetch();
        }

    }

    public function checkInvoice()
    {
        $id = request()->param('id');

        $billinvoice = Db::table("billinvoice")->where("id",$id)->find();

        if(!empty($billinvoice["invoiceFileUrl"])){

            return $this->redirect($billinvoice['invoiceFileUrl']);
        }
        //return $this->redirect($billinvoice['invoiceFileUrl']);
        //判断房号是否相同
        $communityinfo = (new billService())->communityName($billinvoice['community_id']);

        $propertyinfo = (new billService())->propertyInfo($communityinfo['property_id']);

        $serviceinfo = (new billService())->serviceInfo($propertyinfo['service_id']);

        $invoiceConfig=(new invoiceService())->getInvoiceConfig($serviceinfo);
        if($invoiceConfig["errCode"]!='0'){
            return $invoiceConfig["errMsg"];
        }

        $appKey = $invoiceConfig["appKey"];
        $appSecret = $invoiceConfig["appSecret"];
        $token = $invoiceConfig["token"];// please store the token and refresh it before expired

        $taxnum = $serviceinfo["fp_saler_tax_num"];

        $url = "https://sdk.nuonuo.com/open/v1/services";

        $timestmp = time();// change to online domain
        $method = $invoiceConfig["queryInvoiceMethod"]; // change to your method
        $senid = uniqid(); // generate your meaningful senid
        $body = json_encode(
            array(
                "invoiceSerialNum" => array($billinvoice['invoice_serial_num'])
            )
        );

        if($serviceinfo["fp_version"]=="v2"){
            $body = json_encode(
                array(
                    "serialNos" => array($billinvoice['invoice_serial_num'])
                )
            );
        }

        $result = InvoiceApi::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);


        $result = json_decode($result, true);
        //	echo "<pre>";
        //var_dump($result);die;

        if($result['code'] == 'E0000'){
            $info["invoiceCode"]=$result["result"][0]['invoiceCode'];
            $info["invoiceNum"]=$result["result"][0]['invoiceNo'];
            if(isset($result["result"][0]['invoiceFileUrl'])){
                $info["invoiceFileUrl"]=$result["result"][0]['invoiceFileUrl'];
            }else if(isset($result["result"][0]['pdfUrl'])){
                $info["invoiceFileUrl"]=$result["result"][0]['pdfUrl'];
            }

            Db::table("billinvoice")->where("id",$id)->update($info);

            $billid=unserialize($billinvoice["billid"]);
            foreach ($billid as $key => $value) {
                Db::table("bill")
                    ->where('id',$value)
                    ->update([
                        "invoiceFileUrl"=>$info['invoiceFileUrl'],
                        "invoiceNum"=>$info["invoiceNum"],
                        "invoiceCode"=>$info['invoiceCode'],

                        "invoice_type"=>1
                    ]);
            }
            return $this->redirect($result['result'][0]['invoiceFileUrl']);
        }else{
            return json(['error' => $result['describe']]);
        }
        return $res;
    }
    public function checkInvoiceRed()
    {
        $id = request()->param('id');

        $billinvoice = Db::table("billinvoice")->where("id",$id)->find();

        if(!empty($billinvoice["invoiceFileUrlRed"])){

            return $this->redirect($billinvoice['invoiceFileUrlRed']);
        }

        //return $this->redirect($billinvoice['invoiceFileUrl']);
        //判断房号是否相同
        $communityinfo = (new billService())->communityName($billinvoice['community_id']);

        $propertyinfo = (new billService())->propertyInfo($communityinfo['property_id']);

        $serviceinfo = (new billService())->serviceInfo($propertyinfo['service_id']);

        //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second < 86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $access_token = $this->accessToken($serviceinfo['fp_app_key'],$serviceinfo['fp_app_secret']);
            //return $access_token;
        }

        $timestmp = time();

        $appKey = $serviceinfo["fp_app_key"];
        $appSecret = $serviceinfo["fp_app_secret"];
        $token = $access_token;// please store the token and refresh it before expired
        $taxnum = $serviceinfo["fp_saler_tax_num"];

        $url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
        $method = "nuonuo.electronInvoice.CheckEInvoice"; // change to your method
        $senid = uniqid(); // generate your meaningful senid
        $body = json_encode(
            array(
                "invoiceSerialNum" => array($billinvoice['invoice_serial_num_red'])
            )
        );

        $result = InvoiceApi::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);


        $result = json_decode($result, true);


        if($result['code'] == 'E0000'){

            $info["invoiceNumRed"]=$result["result"][0]['invoiceNum'];
            $info["invoiceFileUrlRed"]=$result["result"][0]['invoiceFileUrl'];
            Db::table("billinvoice")->where("id",$id)->update($info);

            $billid=unserialize($billinvoice["billid"]);
            foreach ($billid as $key => $value) {
                Db::table("bill")
                    ->where('id',$value)
                    ->update([
                        "invoiceFileUrl"=>$result['result'][0]['invoiceFileUrl'],
                        "invoiceNum"=>$result['result'][0]["invoiceNum"],
                        "invoiceCode"=>$result['result'][0]['invoiceCode'],

                        "invoice_type"=>2
                    ]);
            }
            return $this->redirect($result['result'][0]['invoiceFileUrl']);
        }else{
            return json(['error' => $result['describe']]);
        }
        return $res;
    }

    public function invoiceExportExcel(){
        $export = request()->param('export');
        $export = str_replace("|","\"",$export);
        $where = json_decode($export,true);

        $exportb = request()->param('exportb');
        $exportb = str_replace("|","\"",$exportb);
        $whereb = json_decode($exportb,true);
        //查询小区信息
        $com = $this->pidTokenId();
        $community_id = $com['community_id'];



        //查询账单数据
        $invoicelist = Db::table("billinvoice")
            ->alias("a")
            ->join("roominfo b","a.out_room_id=b.out_room_id")
            ->join("community c","a.community_id=c.community_id")
            ->where("a.community_id","in",$community_id)
            ->where($where)
            ->where($whereb)
            ->field("a.*,b.address,b.owner_name,b.owner_phone,c.community_name")

            ->order("id desc")
            ->select()->toArray();
        //查询账单条数
        $number = Db::table("billinvoice")
            ->alias("a")
            ->where("a.community_id","in",$community_id)
            ->where($where)
            ->where($whereb)
            ->count();
        if(empty($invoicelist)){
            return json(['error' => '没有账单数据']);
        }

        //var_dump($billList);die;
        //设置表头
        //引入PHPExcel类
        vendor('PHPExcel.PHPExcel.Reader.Excel2007');
        $objPHPExcel = new \PHPExcel();
        //设置表头
        $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', '小区名称')
            ->setCellValue('B1', '发票抬头/业主房号')
            ->setCellValue('C1', '姓名')
            ->setCellValue('D1', '手机')
            ->setCellValue('E1', '含税金额')
            ->setCellValue('F1', '发票号码')
            ->setCellValue('G1', '发票类型')
            ->setCellValue('H1', '开票时间')
            ;

        $i=2;  //定义一个i变量，目的是在循环输出数据是控制行数
          //计算有多少条数据
        for ($i = 2; $i <= $number+1; $i++) {
            $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $invoicelist[$i-2]["community_name"]);
            $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, $invoicelist[$i-2]['address']);
            $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $invoicelist[$i-2]["owner_name"]);
            $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, $invoicelist[$i-2]['owner_phone']);
            $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, $invoicelist[$i-2]['pay_money']);


            //判断账单状态
            $invoice_type="蓝票";
            $invoiceNum=$invoicelist[$i-2]['invoiceNum'];
            if($invoicelist[$i-2]["invoice_type"] == '2'){
                $invoice_type="红票";
                $invoiceNum=$invoicelist[$i-2]['invoiceNumRed'];
            }
            $objPHPExcel->getActiveSheet()->setCellValue('F' . $i, $invoiceNum);
            $objPHPExcel->getActiveSheet()->setCellValue('G' . $i, $invoice_type);
            $objPHPExcel->getActiveSheet()->setCellValue('H' . $i, $invoicelist[$i-2]['invoice_time']);

        }
        $objPHPExcel->getActiveSheet()->setTitle('发票信息');      //设置sheet的名称
        $objPHPExcel->setActiveSheetIndex(0);                   //设置sheet的起始位置
        header('Content-Disposition: attachment;filename="发票信息.xls"');
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        $PHPWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel,"Excel2007"); //通过PHPExcel_IOFactory的写函数将上面数据写出来
        $PHPWriter->save("php://output"); //表示在$path路径下面生成demo.xlsx文件
    }


    //当access_token超时时，获取access_token
    public function accessToken($client_id,$client_secret){
        $res = InvoiceApi::getMerchantToken($client_id, $client_secret);
        $tmpInfo = json_decode($res);


        if(property_exists($tmpInfo,'error')){
            //var_dump($tmpInfo);die;
            //return $tmpInfo;
            $this->error($tmpInfo->error.',access_token获取失败');
        }
        $data['fp_access_token'] = $tmpInfo->access_token;//获取access_token
        $data['fp_expires_in'] = date('Y-m-d H:i:s',time());
        $data['id'] = (new billService())->serviceFpAppKey($client_id);
        // 存储access_token
        $result = (new billService())->serviceUpdate($data);
        return $data['fp_access_token'];
        // $tmpInfo = '{"access_token":"10ffd45208fb4464aa6fee00vthjozss","expires_in":86400}';

    }




}